package com.silence.gmall.listener;

import cn.idev.excel.context.AnalysisContext;
import cn.idev.excel.event.AnalysisEventListener;
import cn.idev.excel.exception.ExcelDataConvertException;
import com.google.common.collect.Lists;
import com.silence.gmall.base.BaseExcelBean;
import com.silence.gmall.base.BaseExcelErrorMessage;
import com.silence.gmall.handler.ExcelValidateHandler;
import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections4.CollectionUtils;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;

/**
 * @Author silence
 * @Email 792245022@qq.com
 * @Date 2025-06-11 14:50
 * @Description excel上传监听器
 */
@Slf4j
@NoArgsConstructor
public abstract class AbstractEasyExcelListener<T extends BaseExcelBean> extends AnalysisEventListener<T> {

    /**
     * 批次大小
     */
    private int batchCount = 100;

    /**
     * 错误信息列表
     */
    @Getter
    private final List<BaseExcelErrorMessage> errList = new ArrayList<>();

    /**
     * 数据列表
     */
    @Getter
    private final List<T> dataList = new ArrayList<>();

    /**
     * 处理数据
     *
     * @param exception 异常信息
     * @param context   分析上下文
     */
    @Override
    public void onException(Exception exception, AnalysisContext context) {
        if (exception instanceof ExcelDataConvertException excelDataConvertException) {
            BaseExcelErrorMessage error = new BaseExcelErrorMessage(excelDataConvertException.getRowIndex(),
                    excelDataConvertException.getColumnIndex(), "数据转换异常");
            this.errList.add(error);
        }
    }

    /**
     * 处理数据
     *
     * @param t               实体类
     * @param analysisContext 分析上下文
     */
    @Override
    public void invoke(T t, AnalysisContext analysisContext) {
        boolean noErr = true;
        List<Map<String, Object>> errors = Lists.newArrayList();

        try {
            errors = ExcelValidateHandler.validateEntity(t);
        } catch (NoSuchFieldException e) {
            log.error("Excel解析异常：", e);
        }

        if (CollectionUtils.isNotEmpty(errors)) {
            noErr = false;
            errors.forEach(e -> {
                BaseExcelErrorMessage excelCheckErrDto = new BaseExcelErrorMessage(analysisContext.readRowHolder().getRowIndex(),
                        (Integer) e.get("column"), (String) e.get("message"));
                this.errList.add(excelCheckErrDto);
            });
        }

        if (noErr) {
            t.setRowIndex(analysisContext.readRowHolder().getRowIndex());
            this.dataList.add(t);
        }

        if (this.dataList.size() >= this.batchCount) {
            this.saveData(this.dataList);
            this.dataList.clear();
        }

    }

    /**
     * 处理完成
     *
     * @param analysisContext 分析上下文
     */
    @Override
    public void doAfterAllAnalysed(AnalysisContext analysisContext) {
        this.saveData(this.dataList);
    }

    /**
     * 保存数据
     *
     * @param dataList 数据列表
     */
    protected abstract void saveData(List<T> dataList);

    /**
     * 设置批次大小
     *
     * @param batchCount 批次大小
     * @return 当前实例
     */
    public AbstractEasyExcelListener<T> setBatchCount(int batchCount) {
        this.batchCount = batchCount;
        return this;
    }
}
